# -*- coding: utf-8 -*-
"""
模型正则化和岭回归
Created on Tue Apr 10 09:16:03 2018

@author: Allen
"""
import numpy as np
import matplotlib.pyplot as plt

np.random.seed( 42 )
x = np.random.uniform( -3.0, 3.0, size = 100 )
X = x.reshape( -1, 1 )
y = 0.5 * x + 3 + np.random.normal( 0, 1, size = 100 )

plt.scatter( x, y )
plt.show()


from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression

def PolynomialRegression( degree ):
    return Pipeline([
            ( "poly", PolynomialFeatures( degree = degree ) ),
            ( "std_scaler", StandardScaler() ),
            ( "lin_reg", LinearRegression() )
            ])
from sklearn.model_selection import train_test_split
np.random.seed( 666 )
X_train, X_test, y_train, y_test = train_test_split( X, y )

from sklearn.metrics import mean_squared_error

poly_reg = PolynomialRegression( degree = 20 )
poly_reg.fit( X_train, y_train )
y_poly_predict = poly_reg.predict( X_test )
print( mean_squared_error( y_test, y_poly_predict ) ) # 167.940108614

def plot_model( model ):
    X_plot = np.linspace( -3, 3, 100 ).reshape( 100, 1 )
    y_plot = model.predict( X_plot )
    
    plt.scatter( x, y )
    plt.plot( X_plot[:, 0], y_plot, color = "r" )
    plt.axis( [ -4, 4, 0, 6 ] )
    plt.show()
    
plot_model( poly_reg )

## 使用岭回归
from sklearn.linear_model import Ridge
def RidgeRegression( degree, alpha ):
    return Pipeline([
                ( "poly", PolynomialFeatures( degree = degree ) ),
                ( "std_scaler", StandardScaler() ),
                ( "ridge_reg", Ridge( alpha = alpha ) )
            ])
ridge1_reg = RidgeRegression( 20, 0.0001 )
ridge1_reg.fit( X_train, y_train )
y1_predict = ridge1_reg.predict( X_test )
print( mean_squared_error( y_test, y1_predict ) ) 
plot_model( ridge1_reg )

ridge2_reg = RidgeRegression( 20, 1 )
ridge2_reg.fit( X_train, y_train )
y2_predict = ridge2_reg.predict( X_test )
print( mean_squared_error( y_test, y2_predict ) ) 
plot_model( ridge2_reg )

ridge3_reg = RidgeRegression( 20, 100 )
ridge3_reg.fit( X_train, y_train )
y3_predict = ridge3_reg.predict( X_test )
print( mean_squared_error( y_test, y3_predict ) ) 
plot_model( ridge3_reg )

ridge4_reg = RidgeRegression( 20, 10000000 )
ridge4_reg.fit( X_train, y_train )
y4_predict = ridge4_reg.predict( X_test )
print( mean_squared_error( y_test, y4_predict ) ) 
plot_model( ridge4_reg )

'''
总结：
    岭回归 关键是在于超参数alpha 的选用，alpha不同，最终效果也不同
'''










     
    